package com.coursehub.exercise.service.impl;

import com.coursehub.exercise.dto.ExerciseCreateDto;
import com.coursehub.exercise.dto.ExerciseUpdateDto;
import com.coursehub.exercise.dto.ExerciseSubmissionDto;
import com.coursehub.exercise.entity.Exercise;
import com.coursehub.exercise.entity.Question;
import com.coursehub.exercise.entity.CourseQuestionBank;
import com.coursehub.exercise.entity.CourseQuestionBankQuestion;
import com.coursehub.exercise.entity.CourseQuestionBankQuestionId;
import com.coursehub.exercise.entity.ExerciseQuestion;
import com.coursehub.exercise.entity.ExerciseQuestionId;
import com.coursehub.exercise.repository.ExerciseRepository;
import com.coursehub.exercise.repository.QuestionRepository;
import com.coursehub.exercise.repository.ExerciseQuestionRepository;
import com.coursehub.exercise.repository.StudentExerciseRepository;
import com.coursehub.exercise.repository.StudentQuestionAnswerRepository;
import com.coursehub.exercise.repository.CourseQuestionBankRepository;
import com.coursehub.exercise.repository.CourseQuestionBankQuestionRepository;
import com.coursehub.exercise.service.ExerciseService;
import com.coursehub.shared.config.ServiceProperties;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 练习服务实现类
 */
@Service
@RequiredArgsConstructor
@Transactional
public class ExerciseServiceImpl implements ExerciseService {
    
    private static final Logger log = LoggerFactory.getLogger(ExerciseServiceImpl.class);
    
    private final ExerciseRepository exerciseRepository;
    private final QuestionRepository questionRepository;
    private final ExerciseQuestionRepository exerciseQuestionRepository;
    private final StudentExerciseRepository studentExerciseRepository;
    private final StudentQuestionAnswerRepository studentQuestionAnswerRepository;
    private final CourseQuestionBankRepository courseQuestionBankRepository;
    private final CourseQuestionBankQuestionRepository courseQuestionBankQuestionRepository;
    private final ServiceProperties serviceProperties;
    private final RestTemplate restTemplate;
    
    @Override
    public Exercise createExercise(ExerciseCreateDto createDto) {
        log.info("创建练习: {}", createDto.getExerciseName());
        
        // 验证班级是否存在
        if (!validateClassExists(createDto.getClassesId())) {
            throw new IllegalArgumentException("班级不存在，ID: " + createDto.getClassesId());
        }
        
        // 检查练习名称是否已存在
        if (exerciseRepository.existsByExerciseName(createDto.getExerciseName())) {
            throw new IllegalArgumentException("练习名称已存在: " + createDto.getExerciseName());
        }
        
        // 验证时间逻辑
        if (createDto.getExerciseStartTime().isAfter(createDto.getExerciseDeadline())) {
            throw new IllegalArgumentException("练习开始时间不能晚于截止时间");
        }
        
        Exercise exercise = new Exercise();
        exercise.setExerciseId(UUID.randomUUID().toString());
        BeanUtils.copyProperties(createDto, exercise);
        
        Exercise savedExercise = exerciseRepository.save(exercise);
        log.info("练习创建成功，ID: {}", savedExercise.getExerciseId());
        
        return savedExercise;
    }
    
    @Override
    @Transactional(readOnly = true)
    public Optional<Exercise> getExerciseById(String exerciseId) {
        log.debug("根据ID获取练习: {}", exerciseId);
        return exerciseRepository.findById(exerciseId);
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Exercise> getAllExercises() {
        log.debug("获取所有练习");
        return exerciseRepository.findAll();
    }
    
    @Override
    @Transactional(readOnly = true)
    public Page<Exercise> getExercises(Pageable pageable) {
        log.debug("分页获取练习");
        return exerciseRepository.findAll(pageable);
    }
    
    @Override
    public Exercise updateExercise(String exerciseId, ExerciseUpdateDto updateDto) {
        log.info("更新练习: {}", exerciseId);
        
        Exercise exercise = exerciseRepository.findById(exerciseId)
                .orElseThrow(() -> new IllegalArgumentException("练习不存在，ID: " + exerciseId));
        
        // 更新非空字段
        if (updateDto.getExerciseName() != null) {
            // 检查新名称是否与其他练习冲突
            if (!updateDto.getExerciseName().equals(exercise.getExerciseName()) &&
                exerciseRepository.existsByExerciseName(updateDto.getExerciseName())) {
                throw new IllegalArgumentException("练习名称已存在: " + updateDto.getExerciseName());
            }
            exercise.setExerciseName(updateDto.getExerciseName());
        }
        
        if (updateDto.getExerciseDeadline() != null) {
            exercise.setExerciseDeadline(updateDto.getExerciseDeadline());
        }
        
        if (updateDto.getExerciseStartTime() != null) {
            exercise.setExerciseStartTime(updateDto.getExerciseStartTime());
        }
        
        if (updateDto.getIsMultipleSubmission() != null) {
            exercise.setIsMultipleSubmission(updateDto.getIsMultipleSubmission());
        }
        
        if (updateDto.getExerciseScore() != null) {
            exercise.setExerciseScore(updateDto.getExerciseScore());
        }
        
        // 验证更新后的时间逻辑
        if (exercise.getExerciseStartTime().isAfter(exercise.getExerciseDeadline())) {
            throw new IllegalArgumentException("练习开始时间不能晚于截止时间");
        }
        
        Exercise savedExercise = exerciseRepository.save(exercise);
        log.info("练习更新成功，ID: {}", savedExercise.getExerciseId());
        
        return savedExercise;
    }
    
    @Override
    public void deleteExercise(String exerciseId) {
        log.info("删除练习: {}", exerciseId);
        
        if (!exerciseRepository.existsById(exerciseId)) {
            throw new IllegalArgumentException("练习不存在，ID: " + exerciseId);
        }
        
        exerciseRepository.deleteById(exerciseId);
        log.info("练习删除成功，ID: {}", exerciseId);
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Exercise> searchExercisesByName(String exerciseName) {
        log.debug("根据名称搜索练习: {}", exerciseName);
        return exerciseRepository.findByExerciseNameContainingIgnoreCase(exerciseName);
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Exercise> getExercisesByClassId(String classesId) {
        log.debug("根据班级ID获取练习: {}", classesId);
        return exerciseRepository.findByClassesId(classesId);
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Exercise> getActiveExercisesByClassId(String classesId) {
        log.debug("根据班级ID获取进行中的练习: {}", classesId);
        LocalDateTime now = LocalDateTime.now();
        return exerciseRepository.findActiveExercisesByClassesId(classesId, now);
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Exercise> getFinishedExercisesByClassId(String classesId) {
        log.debug("根据班级ID获取已结束的练习: {}", classesId);
        LocalDateTime now = LocalDateTime.now();
        return exerciseRepository.findFinishedExercisesByClassesId(classesId, now);
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Exercise> getUpcomingExercisesByClassId(String classesId) {
        log.debug("根据班级ID获取未开始的练习: {}", classesId);
        LocalDateTime now = LocalDateTime.now();
        return exerciseRepository.findUpcomingExercisesByClassesId(classesId, now);
    }
    
    @Override
    @Transactional(readOnly = true)
    public boolean existsById(String exerciseId) {
        return exerciseRepository.existsByExerciseId(exerciseId);
    }
    
    @Override
    @Transactional(readOnly = true)
    public boolean existsByName(String exerciseName) {
        return exerciseRepository.existsByExerciseName(exerciseName);
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Exercise> searchExercises(String exerciseName, String classesId, Boolean isMultipleSubmission) {
        log.debug("根据多个条件搜索练习");
        return exerciseRepository.findByMultipleConditions(exerciseName, classesId, isMultipleSubmission);
    }
    
    @Override
    public boolean validateClassExists(String classesId) {
        // 临时跳过班级验证，用于测试练习创建功能
        log.info("临时跳过班级验证，班级ID: {}", classesId);
        return true;
        
        /* 原始验证逻辑 - 暂时注释
        try {
            String url = serviceProperties.getCourseServiceUrl() + "/api/classes/" + classesId + "/exists";
            
            // 调用课程管理服务，返回的是ApiResponse<Boolean>格式
            ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
            
            if (!response.getStatusCode().is2xxSuccessful()) {
                log.error("验证班级存在性失败，HTTP状态码: {}", response.getStatusCode());
                return false;
            }
            
            // 解析ApiResponse<Boolean>格式的响应
            String responseBody = response.getBody();
            if (responseBody != null) {
                // 简单的JSON解析，提取data字段的值
                if (responseBody.contains("\"data\":true")) {
                    return true;
                } else if (responseBody.contains("\"data\":false")) {
                    return false;
                }
            }
            
            log.error("验证班级存在性失败，无法解析响应: {}", responseBody);
            return false;
        } catch (Exception e) {
            log.error("验证班级存在性失败，班级ID: {}, 错误: {}", classesId, e.getMessage());
            return false;
        }
        */
    }
    
    @Override
    public boolean validateClassPermission(String classesId) {
        log.debug("验证班级权限: {}", classesId);
        
        try {
            // 验证班级是否存在
            String existsUrl = serviceProperties.getCourseServiceUrl() + "/api/classes/" + classesId + "/exists";
            ResponseEntity<Map> existsResponse = restTemplate.getForEntity(existsUrl, Map.class);
            
            if (!existsResponse.getStatusCode().is2xxSuccessful() || existsResponse.getBody() == null) {
                log.error("验证班级存在性失败，HTTP状态码: {}", existsResponse.getStatusCode());
                return false;
            }
            
            Map<String, Object> existsApiResponse = existsResponse.getBody();
            if (!Integer.valueOf(200).equals(existsApiResponse.get("code")) || 
                !Boolean.TRUE.equals(existsApiResponse.get("data"))) {
                log.warn("班级不存在: {}", classesId);
                return false;
            }
            
            log.info("班级权限验证通过: {}", classesId);
            return true;
            
        } catch (Exception e) {
            log.error("验证班级权限失败，班级ID: {}, 错误: {}", classesId, e.getMessage(), e);
            return false;
        }
    }
    
    @Override
    public boolean validateClassPermission(String classesId, String userId) {
        log.debug("验证用户对班级的权限: classesId={}, userId={}", classesId, userId);
        
        if (classesId == null || classesId.trim().isEmpty() || userId == null || userId.trim().isEmpty()) {
            log.warn("参数为空，权限验证失败: classesId={}, userId={}", classesId, userId);
            return false;
        }
        
        try {
            // 首先验证班级是否存在
            if (!validateClassPermission(classesId)) {
                return false;
            }
            
            // 检查用户是否为该班级的学生
            String studentUrl = serviceProperties.getCourseServiceUrl() + "/api/classes/" + classesId + "/students/" + userId + "/exists";
            ResponseEntity<Map> studentResponse = restTemplate.getForEntity(studentUrl, Map.class);
            
            if (studentResponse.getStatusCode().is2xxSuccessful() && studentResponse.getBody() != null) {
                Map<String, Object> studentApiResponse = studentResponse.getBody();
                if (Integer.valueOf(200).equals(studentApiResponse.get("code")) && 
                    Boolean.TRUE.equals(studentApiResponse.get("data"))) {
                    log.info("用户{}是班级{}的学生，权限验证通过", userId, classesId);
                    return true;
                }
            }
            
            // 检查用户是否为该班级的教师
            String teacherUrl = serviceProperties.getCourseServiceUrl() + "/api/classes/" + classesId + "/teachers/" + userId + "/exists";
            ResponseEntity<Map> teacherResponse = restTemplate.getForEntity(teacherUrl, Map.class);
            
            if (teacherResponse.getStatusCode().is2xxSuccessful() && teacherResponse.getBody() != null) {
                Map<String, Object> teacherApiResponse = teacherResponse.getBody();
                if (Integer.valueOf(200).equals(teacherApiResponse.get("code")) && 
                    Boolean.TRUE.equals(teacherApiResponse.get("data"))) {
                    log.info("用户{}是班级{}的教师，权限验证通过", userId, classesId);
                    return true;
                }
            }
            
            log.warn("用户{}对班级{}没有访问权限", userId, classesId);
            return false;
            
        } catch (Exception e) {
            log.error("验证用户班级权限失败: classesId={}, userId={}, 错误: {}", classesId, userId, e.getMessage(), e);
            return false;
        }
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Exercise> getAllCourseExercises(String courseId) {
        log.debug("获取课程的所有练习: {}", courseId);
        try {
            // 通过课程服务获取课程下的所有班级ID
            String courseServiceUrl = serviceProperties.getCourseServiceUrl();
            String url = courseServiceUrl + "/api/classes/course/" + courseId;
            List<String> classesIds = restTemplate.getForObject(url, List.class);
            
            if (classesIds == null || classesIds.isEmpty()) {
                return List.of();
            }
            
            // 查询这些班级的所有练习
            return exerciseRepository.findByClassesIdIn(classesIds);
            
        } catch (Exception e) {
            log.error("获取课程练习失败: courseId={}, 错误: {}", courseId, e.getMessage());
            return List.of();
        }
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Exercise> getUnfinishedExercises(String userId, String courseId) {
        log.debug("获取用户在课程中的未完成练习: userId={}, courseId={}", userId, courseId);
        try {
            // 先获取课程下的所有班级ID
            String courseServiceUrl = serviceProperties.getCourseServiceUrl();
            String classesUrl = courseServiceUrl + "/api/classes/course/" + courseId;
            List<String> classesIds = restTemplate.getForObject(classesUrl, List.class);
            
            if (classesIds == null || classesIds.isEmpty()) {
                return List.of();
            }
            
            // 调用学习进度服务获取未完成的练习ID列表
            String progressServiceUrl = serviceProperties.getProgressServiceUrl();
            String url = progressServiceUrl + "/progress/exercise/unfinished/" + userId + "/course/" + courseId;
            
            List<String> unfinishedExerciseIds = restTemplate.getForObject(url, List.class);
            
            if (unfinishedExerciseIds == null || unfinishedExerciseIds.isEmpty()) {
                return List.of();
            }
            
            // 根据练习ID列表查询练习详情
            return exerciseRepository.findByExerciseIdIn(unfinishedExerciseIds);
            
        } catch (Exception e) {
            log.error("获取未完成练习列表失败: userId={}, courseId={}", userId, courseId, e);
            return List.of();
        }
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Exercise> getFinishedExercises(String userId, String courseId) {
        log.debug("获取用户在课程中的已完成练习: userId={}, courseId={}", userId, courseId);
        try {
            // 先获取课程下的所有班级ID
            String courseServiceUrl = serviceProperties.getCourseServiceUrl();
            String classesUrl = courseServiceUrl + "/api/classes/course/" + courseId;
            List<String> classesIds = restTemplate.getForObject(classesUrl, List.class);
            
            if (classesIds == null || classesIds.isEmpty()) {
                return List.of();
            }
            
            // 调用学习进度服务获取已完成的练习ID列表
            String progressServiceUrl = serviceProperties.getProgressServiceUrl();
            String url = progressServiceUrl + "/progress/exercise/completed/" + userId + "/course/" + courseId;
            
            List<String> completedExerciseIds = restTemplate.getForObject(url, List.class);
            
            if (completedExerciseIds == null || completedExerciseIds.isEmpty()) {
                return List.of();
            }
            
            // 根据练习ID列表查询练习详情
            return exerciseRepository.findByExerciseIdIn(completedExerciseIds);
            
        } catch (Exception e) {
            log.error("获取已完成练习列表失败: userId={}, courseId={}", userId, courseId, e);
            return List.of();
        }
    }
    
    @Override
    @Transactional(readOnly = true)
    public Map<String, Object> getExerciseDetail(String exerciseId, String userId) {
        log.debug("获取练习详情: exerciseId={}, userId={}", exerciseId, userId);
        
        try {
            // 获取练习基本信息
            Optional<Exercise> exerciseOpt = getExerciseById(exerciseId);
            if (exerciseOpt.isEmpty()) {
                return Map.of("success", false, "message", "练习不存在");
            }
            
            Exercise exercise = exerciseOpt.get();
            Map<String, Object> result = new HashMap<>();
            result.put("exerciseId", exercise.getExerciseId());
            result.put("exerciseName", exercise.getExerciseName());
            result.put("exerciseDeadline", exercise.getExerciseDeadline());
            result.put("exerciseStartTime", exercise.getExerciseStartTime());
            result.put("classesId", exercise.getClassesId());
            result.put("isMultipleSubmission", exercise.getIsMultipleSubmission());
            result.put("exerciseScore", exercise.getExerciseScore());
            
            // 如果提供了用户ID，获取用户的完成状态
            if (userId != null && !userId.trim().isEmpty()) {
                try {
                    String progressServiceUrl = serviceProperties.getProgressServiceUrl();
                    String url = progressServiceUrl + "/progress/exercise/status/" + userId + "/" + exerciseId;
                    
                    Map<String, Object> statusResponse = restTemplate.getForObject(url, Map.class);
                    if (statusResponse != null) {
                        result.put("userStatus", statusResponse);
                    }
                } catch (Exception e) {
                    log.warn("获取用户练习状态失败: userId={}, exerciseId={}, 错误: {}", userId, exerciseId, e.getMessage());
                    result.put("userStatus", Map.of("isCompleted", false, "score", null));
                }
            }
            
            return Map.of("success", true, "data", result);
            
        } catch (Exception e) {
            log.error("获取练习详情失败: exerciseId={}, userId={}, 错误: {}", exerciseId, userId, e.getMessage(), e);
            return Map.of("success", false, "message", "获取练习详情失败: " + e.getMessage());
        }
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Map<String, Object>> getExerciseQuestions(String exerciseId) {
        log.debug("获取练习的所有题目: {}", exerciseId);
        
        try {
            // 验证练习是否存在
            if (!existsById(exerciseId)) {
                log.warn("练习不存在: {}", exerciseId);
                return List.of();
            }
            
            // 查询练习关联的题目ID列表
            List<String> questionIds = exerciseQuestionRepository.findQuestionIdsByExerciseId(exerciseId);
            
            if (questionIds.isEmpty()) {
                log.info("练习 {} 没有关联任何题目", exerciseId);
                return List.of();
            }
            
            // 批量查询题目详情
            List<Question> questions = questionRepository.findByQuestionIdIn(questionIds);
            
            // 转换为Map格式返回
            List<Map<String, Object>> result = questions.stream()
                .map(question -> {
                    Map<String, Object> questionMap = new HashMap<>();
                    questionMap.put("questionId", question.getQuestionId());
                    questionMap.put("questionScore", question.getQuestionScore());
                    questionMap.put("type", question.getType());
                    questionMap.put("questionContent", question.getQuestionContent());
                    questionMap.put("questionAnswer", question.getQuestionAnswer());
                    return questionMap;
                })
                .collect(Collectors.toList());
            
            log.info("成功获取练习 {} 的 {} 道题目", exerciseId, result.size());
            return result;
            
        } catch (Exception e) {
            log.error("获取练习题目失败: exerciseId={}, 错误: {}", exerciseId, e.getMessage(), e);
            return List.of();
        }
    }
    
    @Override
    @Transactional
    public Object submitExercise(Object submissionRequest) {
        log.debug("提交练习答案: {}", submissionRequest);
        
        try {
            // 将Object转换为ExerciseSubmissionDto
            ExerciseSubmissionDto submissionDto;
            if (submissionRequest instanceof ExerciseSubmissionDto) {
                submissionDto = (ExerciseSubmissionDto) submissionRequest;
            } else {
                log.error("提交请求格式不正确: {}", submissionRequest);
                return Map.of("success", false, "message", "提交请求格式不正确");
            }
            
            // 验证练习是否存在
            if (!existsById(submissionDto.getExerciseId())) {
                return Map.of("success", false, "message", "练习不存在");
            }
            
            // 调用学习进度服务标记练习完成
            String progressServiceUrl = serviceProperties.getProgressServiceUrl();
            String url = progressServiceUrl + "/progress/exercise/complete";
            
            Map<String, Object> requestBody = Map.of(
                "userId", submissionDto.getUserId(),
                "exerciseId", submissionDto.getExerciseId(),
                "score", submissionDto.getScore()
            );
            
            ResponseEntity<Map> response = restTemplate.postForEntity(url, requestBody, Map.class);
            
            if (response.getStatusCode().is2xxSuccessful()) {
                log.info("练习提交成功: userId={}, exerciseId={}, score={}", 
                    submissionDto.getUserId(), submissionDto.getExerciseId(), submissionDto.getScore());
                return Map.of("success", true, "message", "练习提交成功", "score", submissionDto.getScore());
            } else {
                log.error("调用学习进度服务失败: {}", response.getBody());
                return Map.of("success", false, "message", "提交失败，请稍后重试");
            }
            
        } catch (Exception e) {
            log.error("提交练习失败: {}", e.getMessage(), e);
            return Map.of("success", false, "message", "提交失败: " + e.getMessage());
        }
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Map<String, Object>> getAllStudentExercise(String exerciseId) {
        log.debug("获取学生练习记录: {}", exerciseId);
        try {
            List<com.coursehub.exercise.entity.StudentExercise> records = studentExerciseRepository.findByIdExerciseId(exerciseId);
            return records.stream().map(se -> {
                Map<String, Object> m = new HashMap<>();
                m.put("userId", se.getId() != null ? se.getId().getUserId() : null);
                m.put("exerciseId", se.getId() != null ? se.getId().getExerciseId() : null);
                m.put("studentScore", se.getStudentScore());
                m.put("state", se.getState() != null ? se.getState().name() : null);
                return m;
            }).collect(java.util.stream.Collectors.toList());
        } catch (Exception e) {
            log.error("查询学生练习记录失败: exerciseId={}, 错误: {}", exerciseId, e.getMessage(), e);
            return List.of();
        }
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Map<String, Object>> getAllStudentQuestionAnswer(String exerciseId, String userId) {
        log.debug("获取学生的练习答案: exerciseId={}, userId={}", exerciseId, userId);
        try {
            List<com.coursehub.exercise.entity.StudentQuestionAnswer> answers =
                    studentQuestionAnswerRepository.findByIdExerciseIdAndIdUserId(exerciseId, userId);
            return answers.stream().map(a -> {
                Map<String, Object> m = new HashMap<>();
                m.put("userId", a.getId() != null ? a.getId().getUserId() : null);
                m.put("exerciseId", a.getId() != null ? a.getId().getExerciseId() : null);
                m.put("questionId", a.getId() != null ? a.getId().getQuestionId() : null);
                m.put("studentAnswer", a.getStudentAnswer());
                m.put("isCorrect", a.getIsCorrect());
                m.put("scoreObtained", a.getScoreObtained());
                m.put("answeredAt", a.getAnsweredAt());
                return m;
            }).collect(java.util.stream.Collectors.toList());
        } catch (Exception e) {
            log.error("查询学生答案失败: exerciseId={}, userId={}, 错误: {}", exerciseId, userId, e.getMessage(), e);
            return List.of();
        }
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Map<String, Object>> getClassExercisesForGrading(String classId) {
        log.debug("获取班级待批改的练习列表: {}", classId);
        try {
            List<Exercise> exercises = exerciseRepository.findByClassesId(classId);
            return exercises.stream().map(e -> {
                Map<String, Object> m = new HashMap<>();
                m.put("exerciseId", e.getExerciseId());
                m.put("exerciseName", e.getExerciseName());
                m.put("exerciseStartTime", e.getExerciseStartTime());
                m.put("exerciseDeadline", e.getExerciseDeadline());
                return m;
            }).collect(java.util.stream.Collectors.toList());
        } catch (Exception ex) {
            log.error("获取班级练习失败: classId={}, 错误: {}", classId, ex.getMessage(), ex);
            return List.of();
        }
    }
    
    @Override
    @Transactional(readOnly = true)
    public Object getStudentExerciseForGrading(String exerciseId, String userId) {
        log.debug("获取学生练习详情用于批改: exerciseId={}, userId={}", exerciseId, userId);
        try {
            Map<String, Object> result = new HashMap<>();
            Optional<Exercise> exerciseOpt = exerciseRepository.findById(exerciseId);
            exerciseOpt.ifPresent(e -> {
                result.put("exerciseId", e.getExerciseId());
                result.put("exerciseName", e.getExerciseName());
                result.put("exerciseStartTime", e.getExerciseStartTime());
                result.put("exerciseDeadline", e.getExerciseDeadline());
                result.put("exerciseScore", e.getExerciseScore());
            });
            List<Map<String, Object>> answers = getAllStudentQuestionAnswer(exerciseId, userId);
            result.put("answers", answers);
            return result;
        } catch (Exception e) {
            log.error("获取学生练习详情失败: exerciseId={}, userId={}, 错误: {}", exerciseId, userId, e.getMessage(), e);
            return Map.of("success", false, "message", "获取学生练习详情失败");
        }
    }
    
    @Override
    public Object submitGrades(Object gradeSubmission) {
        log.info("提交批改结果: {}", gradeSubmission);
        try {
            if (!(gradeSubmission instanceof Map)) {
                return Map.of("success", false, "message", "参数格式错误");
            }
            @SuppressWarnings("unchecked")
            Map<String, Object> body = (Map<String, Object>) gradeSubmission;
            String exerciseId = String.valueOf(body.get("exerciseId"));
            String userId = String.valueOf(body.get("userId"));
            @SuppressWarnings("unchecked")
            Map<String, Integer> questionScores = (Map<String, Integer>) body.getOrDefault("questionScores", Map.of());

            int total = 0;
            for (Map.Entry<String, Integer> entry : questionScores.entrySet()) {
                String questionId = entry.getKey();
                Integer score = entry.getValue();
                com.coursehub.exercise.entity.StudentQuestionAnswerId aid =
                        new com.coursehub.exercise.entity.StudentQuestionAnswerId(userId, exerciseId, questionId);
                com.coursehub.exercise.entity.StudentQuestionAnswer ans =
                        studentQuestionAnswerRepository.findById(aid).orElse(null);
                if (ans != null) {
                    ans.setScoreObtained(score);
                    studentQuestionAnswerRepository.save(ans);
                }
                total += score != null ? score : 0;
            }

            // 更新学生总成绩与状态
            com.coursehub.exercise.entity.StudentExerciseId seId =
                    new com.coursehub.exercise.entity.StudentExerciseId(userId, exerciseId);
            com.coursehub.exercise.entity.StudentExercise se = studentExerciseRepository.findById(seId).orElse(null);
            if (se != null) {
                se.setStudentScore(total);
                se.setState(com.coursehub.exercise.entity.StudentExercise.ExerciseState.marked);
                studentExerciseRepository.save(se);
            }

            return Map.of("success", true, "totalScore", total);
        } catch (Exception e) {
            log.error("提交批改结果失败: {}", e.getMessage(), e);
            return Map.of("success", false, "message", e.getMessage());
        }
    }
    
    @Override
    @Transactional
    public void cascadeDeleteExercise(String exerciseId) {
        log.info("级联删除练习及相关数据: {}", exerciseId);
        
        try {
            // 验证练习是否存在
            if (!exerciseRepository.existsById(exerciseId)) {
                log.warn("练习不存在，跳过删除: {}", exerciseId);
                return;
            }
            
            // 1. 删除学生答题记录
            List<com.coursehub.exercise.entity.StudentQuestionAnswer> studentAnswers = 
                studentQuestionAnswerRepository.findByIdExerciseId(exerciseId);
            if (!studentAnswers.isEmpty()) {
                studentQuestionAnswerRepository.deleteAll(studentAnswers);
                log.info("删除了 {} 条学生答题记录", studentAnswers.size());
            }
            
            // 2. 删除学生练习记录
            List<com.coursehub.exercise.entity.StudentExercise> studentExercises = 
                studentExerciseRepository.findByIdExerciseId(exerciseId);
            if (!studentExercises.isEmpty()) {
                studentExerciseRepository.deleteAll(studentExercises);
                log.info("删除了 {} 条学生练习记录", studentExercises.size());
            }
            
            // 3. 删除练习题目关联
            exerciseQuestionRepository.deleteByIdExerciseId(exerciseId);
            log.info("删除了练习题目关联关系");
            
            // 4. 删除练习本身
            exerciseRepository.deleteById(exerciseId);
            log.info("练习级联删除完成，ID: {}", exerciseId);
            
        } catch (Exception e) {
            log.error("级联删除练习失败，ID: {}, 错误: {}", exerciseId, e.getMessage(), e);
            throw new RuntimeException("级联删除练习失败: " + e.getMessage(), e);
        }
    }

    @Override
    @Transactional(readOnly = true)
    public int calculateStudentRank(String exerciseId, String userId) {
        log.debug("计算学生排名: exerciseId={}, userId={}", exerciseId, userId);
        List<com.coursehub.exercise.entity.StudentExercise> list = studentExerciseRepository.findByIdExerciseId(exerciseId);
        if (list == null || list.isEmpty()) {
            return 0;
        }
        list.sort((a, b) -> Integer.compare(
            b.getStudentScore() == null ? 0 : b.getStudentScore(),
            a.getStudentScore() == null ? 0 : a.getStudentScore()
        ));
        int rank = 1;
        Integer prevScore = null;
        int index = 0;
        for (com.coursehub.exercise.entity.StudentExercise se : list) {
            index++;
            Integer score = se.getStudentScore() == null ? 0 : se.getStudentScore();
            if (prevScore == null || !prevScore.equals(score)) {
                rank = index;
                prevScore = score;
            }
            if (se.getId() != null && userId.equals(se.getId().getUserId())) {
                return rank;
            }
        }
        return 0;
    }
    
    @Override
    @Transactional
    public List<Map<String, Object>> loadCourseQuestions(String courseId) {
        log.debug("加载课程题库: {}", courseId);
        
        try {
            // 查找课程题库
            Optional<CourseQuestionBank> courseQuestionBankOpt = courseQuestionBankRepository.findByCourseId(courseId);
            
            CourseQuestionBank courseQuestionBank;
            if (courseQuestionBankOpt.isEmpty()) {
                log.info("课程 {} 尚未创建题库，自动创建", courseId);
                // 自动创建题库
                String courseQuestionBankId = UUID.randomUUID().toString();
                courseQuestionBank = new CourseQuestionBank(courseQuestionBankId, courseId);
                courseQuestionBank = courseQuestionBankRepository.save(courseQuestionBank);
                log.info("为课程 {} 创建了新的题库: {}", courseId, courseQuestionBankId);
                return List.of(); // 新创建的题库没有题目，返回空列表
            }
            
            courseQuestionBank = courseQuestionBankOpt.get();
            String courseQuestionBankId = courseQuestionBank.getCourseQuestionBankId();
            
            // 查询题库中的所有题目ID
            List<String> questionIds = courseQuestionBankQuestionRepository
                .findQuestionIdsByCourseQuestionBankId(courseQuestionBankId);
            
            if (questionIds.isEmpty()) {
                log.info("课程题库 {} 中没有题目", courseQuestionBankId);
                return List.of();
            }
            
            // 批量查询题目详情
            List<Question> questions = questionRepository.findByQuestionIdIn(questionIds);
            
            // 转换为Map格式返回
            List<Map<String, Object>> result = questions.stream()
                .map(question -> {
                    Map<String, Object> questionMap = new HashMap<>();
                    questionMap.put("questionId", question.getQuestionId());
                    questionMap.put("questionScore", question.getQuestionScore());
                    questionMap.put("type", question.getType());
                    questionMap.put("questionContent", question.getQuestionContent());
                    questionMap.put("questionAnswer", question.getQuestionAnswer());
                    return questionMap;
                })
                .collect(Collectors.toList());
            
            log.info("成功加载课程 {} 的题库，共 {} 道题目", courseId, result.size());
            return result;
            
        } catch (Exception e) {
            log.error("加载课程题库失败: courseId={}, 错误: {}", courseId, e.getMessage(), e);
            return List.of();
        }
    }
    
    @Override
    @Transactional
    public Object addQuestionToBank(String courseId, Object questionData) {
        log.info("添加题目到题库: courseId={}", courseId);
        
        try {
            // 验证questionData格式
            if (!(questionData instanceof Map)) {
                return Map.of("success", false, "message", "题目数据格式不正确");
            }
            
            @SuppressWarnings("unchecked")
            Map<String, Object> questionMap = (Map<String, Object>) questionData;
            
            // 验证必要字段
            String questionContent = (String) questionMap.get("questionContent");
            String questionAnswer = (String) questionMap.get("questionAnswer");
            
            // 处理可能的类型转换问题
            Integer questionScore;
            Object scoreObj = questionMap.get("questionScore");
            if (scoreObj instanceof Integer) {
                questionScore = (Integer) scoreObj;
            } else if (scoreObj instanceof Number) {
                questionScore = ((Number) scoreObj).intValue();
            } else if (scoreObj instanceof String) {
                try {
                    questionScore = Integer.parseInt((String) scoreObj);
                } catch (NumberFormatException e) {
                    return Map.of("success", false, "message", "题目分数格式不正确，应为整数");
                }
            } else if (scoreObj instanceof Boolean) {
                // 如果是布尔值，转换为1或0
                questionScore = ((Boolean) scoreObj) ? 1 : 0;
            } else {
                return Map.of("success", false, "message", "题目分数格式不正确，应为整数");
            }
            
            // 处理题目类型
            Integer type;
            Object typeObj = questionMap.get("type");
            if (typeObj instanceof Integer) {
                type = (Integer) typeObj;
            } else if (typeObj instanceof Number) {
                type = ((Number) typeObj).intValue();
            } else if (typeObj instanceof String) {
                try {
                    type = Integer.parseInt((String) typeObj);
                } catch (NumberFormatException e) {
                    return Map.of("success", false, "message", "题目类型格式不正确，应为整数");
                }
            } else if (typeObj instanceof Boolean) {
                // 如果是布尔值，转换为1或0
                type = ((Boolean) typeObj) ? 1 : 0;
            } else {
                return Map.of("success", false, "message", "题目类型格式不正确，应为整数");
            }
            
            if (questionContent == null || questionContent.trim().isEmpty() ||
                questionAnswer == null || questionAnswer.trim().isEmpty() ||
                questionScore <= 0 ||
                (type != 0 && type != 1)) {
                return Map.of("success", false, "message", "题目数据不完整或格式不正确");
            }
            
            // 查找或创建课程题库
            CourseQuestionBank courseQuestionBank;
            Optional<CourseQuestionBank> courseQuestionBankOpt = courseQuestionBankRepository.findByCourseId(courseId);
            
            if (courseQuestionBankOpt.isEmpty()) {
                // 创建新的课程题库
                String courseQuestionBankId = UUID.randomUUID().toString();
                courseQuestionBank = new CourseQuestionBank(courseQuestionBankId, courseId);
                courseQuestionBank = courseQuestionBankRepository.save(courseQuestionBank);
                log.info("为课程 {} 创建了新的题库: {}", courseId, courseQuestionBankId);
            } else {
                courseQuestionBank = courseQuestionBankOpt.get();
            }
            
            // 创建题目
            String questionId = UUID.randomUUID().toString();
            Question question = new Question();
            question.setQuestionId(questionId);
            question.setQuestionContent(questionContent.trim());
            question.setQuestionAnswer(questionAnswer.trim());
            question.setQuestionScore(questionScore);
            question.setType(type);
            
            question = questionRepository.save(question);
            log.info("创建了新题目: {}", questionId);
            
            // 建立题库和题目的关联
            CourseQuestionBankQuestionId relationId = new CourseQuestionBankQuestionId(
                courseQuestionBank.getCourseQuestionBankId(), questionId);
            CourseQuestionBankQuestion relation = new CourseQuestionBankQuestion(
                relationId, courseQuestionBank, question);
            
            courseQuestionBankQuestionRepository.save(relation);
            log.info("建立了题库和题目的关联关系");
            
            // 检查是否需要关联到练习
            String exerciseId = (String) questionMap.get("exerciseId");
            if (exerciseId != null && !exerciseId.trim().isEmpty()) {
                addQuestionToExercise(exerciseId, questionId);
            }
            
            return Map.of(
                "success", true, 
                "message", "题目添加成功",
                "questionId", questionId,
                "courseQuestionBankId", courseQuestionBank.getCourseQuestionBankId()
            );
            
        } catch (Exception e) {
            log.error("添加题目到题库失败: courseId={}, 错误: {}", courseId, e.getMessage(), e);
            return Map.of("success", false, "message", "添加题目失败: " + e.getMessage());
        }
    }
    
    /**
     * 添加题目到练习
     * @param exerciseId 练习ID
     * @param questionId 题目ID
     */
    @Override
    @Transactional
    public void addQuestionToExercise(String exerciseId, String questionId) {
        log.info("添加题目到练习: exerciseId={}, questionId={}", exerciseId, questionId);
        
        try {
            // 验证练习是否存在
            Optional<Exercise> exerciseOpt = exerciseRepository.findById(exerciseId);
            if (exerciseOpt.isEmpty()) {
                log.warn("练习不存在: {}", exerciseId);
                return;
            }
            
            // 验证题目是否存在
            Optional<Question> questionOpt = questionRepository.findById(questionId);
            if (questionOpt.isEmpty()) {
                log.warn("题目不存在: {}", questionId);
                return;
            }
            
            // 检查关联是否已存在
            if (exerciseQuestionRepository.existsByIdExerciseIdAndIdQuestionId(exerciseId, questionId)) {
                log.info("练习和题目的关联已存在: exerciseId={}, questionId={}", exerciseId, questionId);
                return;
            }
            
            // 创建练习和题目的关联
            ExerciseQuestionId relationId = new ExerciseQuestionId(exerciseId, questionId);
            ExerciseQuestion relation = new ExerciseQuestion(relationId, exerciseOpt.get(), questionOpt.get());
            
            exerciseQuestionRepository.save(relation);
            log.info("成功添加题目到练习: exerciseId={}, questionId={}", exerciseId, questionId);
            
        } catch (Exception e) {
            log.error("添加题目到练习失败: exerciseId={}, questionId={}, 错误: {}", 
                    exerciseId, questionId, e.getMessage(), e);
        }
    }
    
    @Override
    @Transactional
    public void deleteQuestionFromBank(String courseId, String questionId) {
        log.info("从题库删除题目: courseId={}, questionId={}", courseId, questionId);
        
        try {
            // 查找课程题库
            Optional<CourseQuestionBank> courseQuestionBankOpt = courseQuestionBankRepository.findByCourseId(courseId);
            
            if (courseQuestionBankOpt.isEmpty()) {
                log.warn("课程 {} 没有题库，无法删除题目", courseId);
                throw new IllegalArgumentException("课程题库不存在");
            }
            
            CourseQuestionBank courseQuestionBank = courseQuestionBankOpt.get();
            String courseQuestionBankId = courseQuestionBank.getCourseQuestionBankId();
            
            // 检查题目是否在题库中
            if (!courseQuestionBankQuestionRepository.existsByIdCourseQuestionBankIdAndIdQuestionId(
                    courseQuestionBankId, questionId)) {
                log.warn("题目 {} 不在课程 {} 的题库中", questionId, courseId);
                throw new IllegalArgumentException("题目不在指定课程的题库中");
            }
            
            // 检查题目是否正在被练习使用
            List<String> exerciseIds = exerciseQuestionRepository.findExerciseIdsByQuestionId(questionId);
            if (!exerciseIds.isEmpty()) {
                log.warn("题目 {} 正在被 {} 个练习使用，无法删除", questionId, exerciseIds.size());
                throw new IllegalStateException("题目正在被练习使用，无法删除");
            }
            
            // 检查题目是否有学生答题记录
            List<com.coursehub.exercise.entity.StudentQuestionAnswer> studentAnswers = 
                studentQuestionAnswerRepository.findByIdQuestionId(questionId);
            if (!studentAnswers.isEmpty()) {
                log.warn("题目 {} 有学生答题记录，无法删除", questionId);
                throw new IllegalStateException("题目有学生答题记录，无法删除");
            }
            
            // 删除题库和题目的关联
            courseQuestionBankQuestionRepository.deleteByIdCourseQuestionBankIdAndIdQuestionId(
                courseQuestionBankId, questionId);
            log.info("删除了题库和题目的关联关系");
            
            // 检查题目是否还被其他题库使用
            List<CourseQuestionBankQuestion> otherRelations = 
                courseQuestionBankQuestionRepository.findByIdQuestionId(questionId);
            
            if (otherRelations.isEmpty()) {
                // 如果题目没有被其他题库使用，则删除题目本身
                questionRepository.deleteById(questionId);
                log.info("删除了题目本身: {}", questionId);
            } else {
                log.info("题目 {} 还被其他 {} 个题库使用，保留题目", questionId, otherRelations.size());
            }
            
            log.info("成功从题库删除题目: courseId={}, questionId={}", courseId, questionId);
            
        } catch (IllegalArgumentException | IllegalStateException e) {
            log.warn("删除题目失败: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("从题库删除题目失败: courseId={}, questionId={}, 错误: {}", 
                courseId, questionId, e.getMessage(), e);
            throw new RuntimeException("删除题目失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    @Transactional(readOnly = true)
    public String getClassesIdByCourseAndUser(String courseId, String userId) {
        log.debug("获取班级ID: courseId={}, userId={}", courseId, userId);
        try {
            String url = serviceProperties.getCourseServiceUrl() + "/api/classes/course/" + courseId + "/user/" + userId + "/id";
            ResponseEntity<Map> response = restTemplate.getForEntity(url, Map.class);
            
            if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) {
                Map<String, Object> apiResponse = response.getBody();
                if (Boolean.TRUE.equals(apiResponse.get("success")) && apiResponse.get("data") != null) {
                    return apiResponse.get("data").toString();
                }
            }
        } catch (Exception e) {
            log.error("获取班级ID失败: courseId={}, userId={}, 错误: {}", courseId, userId, e.getMessage());
        }
        return null;
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Map<String, Object>> getClassesAsTeacher(String courseId, String userId) {
        log.debug("获取用户作为教师的所有班级: courseId={}, userId={}", courseId, userId);
        try {
            String url = serviceProperties.getCourseServiceUrl() + "/api/classes/course/" + courseId + "/teacher/" + userId;
            ResponseEntity<Map> response = restTemplate.getForEntity(url, Map.class);
            
            if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) {
                Map<String, Object> apiResponse = response.getBody();
                if (Boolean.TRUE.equals(apiResponse.get("success")) && apiResponse.get("data") != null) {
                    @SuppressWarnings("unchecked")
                    List<Map<String, Object>> classes = (List<Map<String, Object>>) apiResponse.get("data");
                    return classes;
                }
            }
        } catch (Exception e) {
            log.error("获取教师班级失败: courseId={}, userId={}, 错误: {}", courseId, userId, e.getMessage());
        }
        return List.of();
    }
    
    @Override
    @Transactional(readOnly = true)
    public String getUserRole(String courseId, String userId) {
        log.info("[DEBUG] 开始获取用户角色: courseId={}, userId={}", courseId, userId);
        
        try {
            // 通过API网关调用course-service，这样可以传递用户头信息
            // 1. 先检查用户是否为该课程的学生
            String studentUrl = "http://localhost:8081/api/courses/" + courseId + "/students";
            log.info("[DEBUG] 调用学生API (通过网关): {}", studentUrl);
            
            ResponseEntity<Map> studentResponse = restTemplate.getForEntity(studentUrl, Map.class);
            log.info("[DEBUG] 学生API响应状态: {}", studentResponse.getStatusCode());
            log.info("[DEBUG] 学生API响应体: {}", studentResponse.getBody());
            
            if (studentResponse.getStatusCode().is2xxSuccessful() && studentResponse.getBody() != null) {
                Map<String, Object> apiResponse = studentResponse.getBody();
                log.info("[DEBUG] 学生API响应码: {}", apiResponse.get("code"));
                log.info("[DEBUG] 学生API数据: {}", apiResponse.get("data"));
                
                if (Integer.valueOf(200).equals(apiResponse.get("code")) && apiResponse.get("data") != null) {
                    @SuppressWarnings("unchecked")
                    List<String> students = (List<String>) apiResponse.get("data");
                    log.info("[DEBUG] 课程学生列表: {}", students);
                    log.info("[DEBUG] 检查用户{}是否在学生列表中: {}", userId, students.contains(userId));
                    
                    if (students.contains(userId)) {
                        log.info("[DEBUG] 用户{}是课程{}的学生", userId, courseId);
                        return "student";
                    }
                } else {
                    log.warn("[DEBUG] 学生API响应格式异常: code={}, data={}", apiResponse.get("code"), apiResponse.get("data"));
                }
            } else {
                log.warn("[DEBUG] 学生API调用失败: 状态码={}, 响应体={}", studentResponse.getStatusCode(), studentResponse.getBody());
            }
            
            // 2. 再检查用户是否为该课程的教师
            String teacherUrl = "http://localhost:8081/api/courses/" + courseId + "/teachers";
            log.info("[DEBUG] 调用教师API (通过网关): {}", teacherUrl);
            
            ResponseEntity<Map> teacherResponse = restTemplate.getForEntity(teacherUrl, Map.class);
            log.info("[DEBUG] 教师API响应状态: {}", teacherResponse.getStatusCode());
            log.info("[DEBUG] 教师API响应体: {}", teacherResponse.getBody());
            
            if (teacherResponse.getStatusCode().is2xxSuccessful() && teacherResponse.getBody() != null) {
                Map<String, Object> apiResponse = teacherResponse.getBody();
                log.info("[DEBUG] 教师API响应码: {}", apiResponse.get("code"));
                log.info("[DEBUG] 教师API数据: {}", apiResponse.get("data"));
                
                if (Integer.valueOf(200).equals(apiResponse.get("code")) && apiResponse.get("data") != null) {
                    @SuppressWarnings("unchecked")
                    List<String> teachers = (List<String>) apiResponse.get("data");
                    log.info("[DEBUG] 课程教师列表: {}", teachers);
                    log.info("[DEBUG] 检查用户{}是否在教师列表中: {}", userId, teachers.contains(userId));
                    
                    if (teachers.contains(userId)) {
                        log.info("[DEBUG] 用户{}是课程{}的教师", userId, courseId);
                        return "teacher";
                    }
                } else {
                    log.warn("[DEBUG] 教师API响应格式异常: code={}, data={}", apiResponse.get("code"), apiResponse.get("data"));
                }
            } else {
                log.warn("[DEBUG] 教师API调用失败: 状态码={}, 响应体={}", teacherResponse.getStatusCode(), teacherResponse.getBody());
            }
            
        } catch (Exception e) {
            log.error("[DEBUG] 获取用户角色异常: courseId={}, userId={}, 错误类型: {}, 错误信息: {}", 
                    courseId, userId, e.getClass().getSimpleName(), e.getMessage(), e);
        }
        
        // 如果既不是学生也不是教师，返回undefined
        log.warn("[DEBUG] 用户{}在课程{}中既不是学生也不是教师，返回undefined", userId, courseId);
        return "undefined";
    }
}